package generator.mybatis.plugin;

import generator.mybatis.util.GeneratorUtil;
import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.FullyQualifiedTable;
import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.Plugin;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.internal.util.JavaBeansUtil;

import java.util.ArrayList;
import java.util.List;

import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;

/**
 * 2019/4/23
 * 生成请求、返回Dto
 *
 * @author machuanpeng
 */
public class MyDtoPlugin extends PluginAdapter {
    /**
     * 请求参数dto包路径
     */
    private String requestPackage;
    /**
     * 返回参数dto包路径
     */
    private String responsePackage;
    /**
     * 目标
     */
    private String targetProject;

    @Override
    public boolean validate(List<String> warnings) {
        requestPackage = properties.getProperty("requestPackage");
        responsePackage = properties.getProperty("responsePackage");
        targetProject = properties.getProperty("targetProject");
        if (!stringHasValue(targetProject)) {
            targetProject = "mybatis/src/main/java";
        }
        return stringHasValue(requestPackage) && stringHasValue(responsePackage);
    }

    /**
     * 添加文件.
     * 2019/6/14
     *
     * @param introspectedTable introspectedTable
     * @return java.util.List<org.mybatis.generator.api.GeneratedJavaFile>
     * @author machuanpeng
     */
    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
        FullyQualifiedTable fullyQualifiedTable = introspectedTable.getFullyQualifiedTable();
        Plugin plugins = context.getPlugins();
        CommentGenerator commentGenerator = context.getCommentGenerator();

        //model名称
        String domainName = fullyQualifiedTable.getDomainObjectName();

        //requestDto
        FullyQualifiedJavaType requestJavaType =
                new FullyQualifiedJavaType(requestPackage + "." + domainName + "ReqDTO");
        TopLevelClass reqTopLevelClass = new TopLevelClass(requestJavaType);
        reqTopLevelClass.setVisibility(JavaVisibility.PUBLIC);
        commentGenerator.addModelClassComment(reqTopLevelClass, introspectedTable);

        //responseDto
        FullyQualifiedJavaType responseJavaType =
                new FullyQualifiedJavaType(responsePackage + "." + domainName + "ResDTO");
        TopLevelClass resTopLevelClass = new TopLevelClass(responseJavaType);
        resTopLevelClass.setVisibility(JavaVisibility.PUBLIC);
        commentGenerator.addModelClassComment(resTopLevelClass, introspectedTable);

        //添加属性
        List<IntrospectedColumn> introspectedColumns = GeneratorUtil.getAllColumns(introspectedTable);
        for (IntrospectedColumn introspectedColumn : introspectedColumns) {

            Field field = JavaBeansUtil.getJavaBeansField(introspectedColumn, context, introspectedTable);
            if (plugins.modelFieldGenerated(field, reqTopLevelClass,
                    introspectedColumn, introspectedTable,
                    ModelClassType.BASE_RECORD)) {
                reqTopLevelClass.addField(field);
                reqTopLevelClass.addImportedType(field.getType());
            }
            if (plugins.modelFieldGenerated(field, resTopLevelClass,
                    introspectedColumn, introspectedTable,
                    ModelClassType.BASE_RECORD)) {
                resTopLevelClass.addField(field);
                resTopLevelClass.addImportedType(field.getType());
            }

            Method method = JavaBeansUtil.getJavaBeansGetter(introspectedColumn, context, introspectedTable);
            if (plugins.modelGetterMethodGenerated(method, reqTopLevelClass,
                    introspectedColumn, introspectedTable,
                    ModelClassType.BASE_RECORD)) {
                reqTopLevelClass.addMethod(method);
            }
            if (plugins.modelGetterMethodGenerated(method, resTopLevelClass,
                    introspectedColumn, introspectedTable,
                    ModelClassType.BASE_RECORD)) {
                resTopLevelClass.addMethod(method);
            }

            if (!introspectedTable.isImmutable()) {
                method = JavaBeansUtil
                        .getJavaBeansSetter(introspectedColumn, context, introspectedTable, requestJavaType);
                if (plugins.modelSetterMethodGenerated(method, reqTopLevelClass,
                        introspectedColumn, introspectedTable,
                        ModelClassType.BASE_RECORD)) {
                    reqTopLevelClass.addMethod(method);
                }
                method = JavaBeansUtil
                        .getJavaBeansSetter(introspectedColumn, context, introspectedTable, responseJavaType);
                if (plugins.modelSetterMethodGenerated(method, resTopLevelClass,
                        introspectedColumn, introspectedTable,
                        ModelClassType.BASE_RECORD)) {
                    resTopLevelClass.addMethod(method);
                }
            }
        }

        List<GeneratedJavaFile> generatedJavaFiles = new ArrayList<>();
        if (context.getPlugins().modelBaseRecordClassGenerated(
                reqTopLevelClass, introspectedTable)) {
            GeneratedJavaFile generatedJavaFile =
                    new GeneratedJavaFile(reqTopLevelClass, targetProject, context.getJavaFormatter());
            generatedJavaFiles.add(generatedJavaFile);
        }
        if (context.getPlugins().modelBaseRecordClassGenerated(
                resTopLevelClass, introspectedTable)) {
            GeneratedJavaFile generatedJavaFile =
                    new GeneratedJavaFile(resTopLevelClass, targetProject, context.getJavaFormatter());
            generatedJavaFiles.add(generatedJavaFile);
        }
        return generatedJavaFiles;
    }

}
